<template>
  <div class="live-preview">
    <div class="preview-header">
      <h3 class="preview-title">
        <el-icon><View /></el-icon>
        实时预览
      </h3>
      <div class="preview-actions">
        <el-button-group>
          <el-button 
            :type="previewScale === 0.5 ? 'primary' : ''"
            size="small"
            @click="setScale(0.5)"
          >
            50%
          </el-button>
          <el-button 
            :type="previewScale === 0.75 ? 'primary' : ''"
            size="small"
            @click="setScale(0.75)"
          >
            75%
          </el-button>
          <el-button 
            :type="previewScale === 1 ? 'primary' : ''"
            size="small"
            @click="setScale(1)"
          >
            100%
          </el-button>
        </el-button-group>
        
        <el-button 
          type="success" 
          :icon="Download"
          @click="exportImage"
          :loading="exporting"
        >
          导出
        </el-button>
      </div>
    </div>
    
    <div class="preview-container">
      <div class="preview-wrapper" :style="previewWrapperStyle">
        <div 
          ref="canvasRef"
          class="preview-canvas"
          :style="canvasStyle"
        >
          <!-- 背景层 -->
          <div class="background-layer" :style="backgroundStyle"></div>
          
          <!-- 图片层 -->
          <div 
            v-if="selectedImage"
            class="image-layer"
            :style="imageLayerStyle"
          >
            <img 
              :src="selectedImage.fileUrl" 
              :alt="selectedImage.originalName"
              class="canvas-image"
              :style="imageStyle"
            />
          </div>
          
          <!-- 文字层 -->
          <div
            v-for="(textArea, index) in textAreas"
            :key="index"
            class="text-layer"
            :style="getTextLayerStyle(textArea, index)"
            :class="{ 'selected': selectedTextIndex === index }"
            @click="selectTextLayer(index)"
          >
            <div 
              class="text-content"
              :style="getTextStyle(textArea)"
              contenteditable
              @input="handleTextEdit(index, $event)"
              @blur="handleTextBlur(index)"
            >
              {{ textArea.content || textArea.placeholder }}
            </div>
            
            <!-- 文字层控制点 -->
            <div class="text-controls" v-if="selectedTextIndex === index">
              <div class="control-point top-left" @mousedown="startResize(index, 'top-left')"></div>
              <div class="control-point top-right" @mousedown="startResize(index, 'top-right')"></div>
              <div class="control-point bottom-left" @mousedown="startResize(index, 'bottom-left')"></div>
              <div class="control-point bottom-right" @mousedown="startResize(index, 'bottom-right')"></div>
              <div class="control-point move" @mousedown="startMove(index)">
                <el-icon><Rank /></el-icon>
              </div>
            </div>
          </div>
          
          <!-- 网格线 -->
          <div class="grid-lines" v-if="showGrid">
            <div class="grid-line vertical" style="left: 33.33%"></div>
            <div class="grid-line vertical" style="left: 66.66%"></div>
            <div class="grid-line horizontal" style="top: 33.33%"></div>
            <div class="grid-line horizontal" style="top: 66.66%"></div>
          </div>
        </div>
      </div>
      
      <!-- 预览工具栏 -->
      <div class="preview-toolbar">
        <div class="toolbar-section">
          <el-checkbox v-model="showGrid" @change="handleGridToggle">
            显示网格
          </el-checkbox>
          <el-checkbox v-model="showRuler" @change="handleRulerToggle">
            显示标尺
          </el-checkbox>
        </div>
        
        <div class="toolbar-section">
          <span class="canvas-info">
            {{ template?.width }}×{{ template?.height }}px
          </span>
        </div>
        
        <div class="toolbar-section">
          <el-button 
            text 
            size="small"
            @click="resetCanvas"
          >
            重置画布
          </el-button>
          <el-button 
            text 
            size="small"
            @click="centerContent"
          >
            居中内容
          </el-button>
        </div>
      </div>
    </div>
    
    <!-- 导出选项对话框 -->
    <el-dialog
      v-model="exportDialogVisible"
      title="导出设置"
      width="400px"
    >
      <el-form :model="exportConfig" label-width="100px">
        <el-form-item label="导出格式">
          <el-radio-group v-model="exportConfig.format">
            <el-radio-button label="png">PNG</el-radio-button>
            <el-radio-button label="jpg">JPG</el-radio-button>
            <el-radio-button label="webp">WebP</el-radio-button>
          </el-radio-group>
        </el-form-item>
        
        <el-form-item label="图片质量" v-if="exportConfig.format !== 'png'">
          <el-slider
            v-model="exportConfig.quality"
            :min="0.1"
            :max="1"
            :step="0.1"
            show-input
          />
        </el-form-item>
        
        <el-form-item label="导出尺寸">
          <el-radio-group v-model="exportConfig.sizeType">
            <el-radio label="original">原始尺寸</el-radio>
            <el-radio label="custom">自定义</el-radio>
          </el-radio-group>
        </el-form-item>
        
        <el-form-item label="自定义尺寸" v-if="exportConfig.sizeType === 'custom'">
          <div class="size-inputs">
            <el-input-number
              v-model="exportConfig.width"
              :min="100"
              :max="4000"
              placeholder="宽度"
            />
            <span>×</span>
            <el-input-number
              v-model="exportConfig.height"
              :min="100"
              :max="4000"
              placeholder="高度"
            />
          </div>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="exportDialogVisible = false">取消</el-button>
        <el-button 
          type="primary" 
          @click="confirmExport"
          :loading="exporting"
        >
          {{ exporting ? '导出中...' : '确定导出' }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, reactive, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { View, Download, Rank } from '@element-plus/icons-vue'
import type { ImageModel } from '@/types'
import html2canvas from 'html2canvas'

interface TextArea {
  placeholder: string
  content: string
  fontSize: number
  color: string
  fontStyles: string[]
  textAlign: string
  position?: { x: number; y: number; width: number; height: number }
}

interface Props {
  template?: any
  selectedImage?: ImageModel
  textAreas?: TextArea[]
  background?: any
}

interface Emits {
  (e: 'text-edit', index: number, content: string): void
  (e: 'text-move', index: number, position: any): void
  (e: 'text-resize', index: number, size: any): void
  (e: 'export-complete', url: string): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// 响应式数据
const canvasRef = ref<HTMLElement>()
const previewScale = ref(1)
const selectedTextIndex = ref(-1)
const showGrid = ref(false)
const showRuler = ref(false)
const exportDialogVisible = ref(false)
const exporting = ref(false)

const exportConfig = reactive({
  format: 'png',
  quality: 0.9,
  sizeType: 'original',
  width: 800,
  height: 600
})

// 拖拽相关状态
const isDragging = ref(false)
const isResizing = ref(false)
const dragStart = ref({ x: 0, y: 0 })
const resizeType = ref('')

// 计算属性
const previewWrapperStyle = computed(() => ({
  transform: `scale(${previewScale.value})`,
  transformOrigin: 'top left'
}))

const canvasStyle = computed(() => {
  if (!props.template) return {}
  
  return {
    width: `${props.template.width}px`,
    height: `${props.template.height}px`,
    position: 'relative',
    overflow: 'hidden',
    border: '1px solid rgba(255, 255, 255, 0.2)',
    borderRadius: '8px'
  }
})

const backgroundStyle = computed(() => {
  if (!props.background) {
    return {
      backgroundColor: props.template?.backgroundColor || '#ffffff'
    }
  }
  
  switch (props.background.type) {
    case 'color':
      return { backgroundColor: props.background.value }
    case 'gradient':
      return {
        background: `linear-gradient(${props.background.direction}, ${props.background.start}, ${props.background.end})`
      }
    case 'image':
      return {
        backgroundImage: `url(${props.background.value})`,
        backgroundSize: 'cover',
        backgroundPosition: 'center'
      }
    default:
      return { backgroundColor: '#ffffff' }
  }
})

const imageLayerStyle = computed(() => {
  if (!props.template) return {}
  
  const imageArea = props.template.layout.imageArea
  return {
    position: 'absolute',
    ...imageArea
  }
})

const imageStyle = computed(() => ({
  width: '100%',
  height: '100%',
  objectFit: 'cover' as const,
  borderRadius: 'inherit'
}))

// 监听模板变化
watch(() => props.template, (newTemplate) => {
  if (newTemplate) {
    exportConfig.width = newTemplate.width
    exportConfig.height = newTemplate.height
  }
}, { immediate: true })

// 方法
const setScale = (scale: number) => {
  previewScale.value = scale
}

const getTextLayerStyle = (textArea: TextArea, index: number) => {
  if (!props.template) return {}
  
  const templateTextArea = props.template.layout.textAreas[index]
  if (!templateTextArea) return {}
  
  const position = textArea.position || {
    x: parseFloat(templateTextArea.style.left),
    y: parseFloat(templateTextArea.style.top),
    width: parseFloat(templateTextArea.style.width),
    height: parseFloat(templateTextArea.style.height)
  }
  
  return {
    position: 'absolute',
    left: typeof position.x === 'string' ? position.x : `${position.x}%`,
    top: typeof position.y === 'string' ? position.y : `${position.y}%`,
    width: typeof position.width === 'string' ? position.width : `${position.width}%`,
    height: typeof position.height === 'string' ? position.height : `${position.height}%`,
    cursor: 'move',
    border: selectedTextIndex.value === index ? '2px dashed #409EFF' : 'none',
    minHeight: '20px'
  }
}

const getTextStyle = (textArea: TextArea) => {
  const fontWeight = textArea.fontStyles.includes('bold') ? 'bold' : 'normal'
  const fontStyle = textArea.fontStyles.includes('italic') ? 'italic' : 'normal'
  const textDecoration = textArea.fontStyles.includes('underline') ? 'underline' : 'none'
  
  return {
    fontSize: `${textArea.fontSize}px`,
    color: textArea.color,
    fontWeight,
    fontStyle,
    textDecoration,
    textAlign: textArea.textAlign,
    width: '100%',
    height: '100%',
    display: 'flex',
    alignItems: 'center',
    justifyContent: textArea.textAlign === 'center' ? 'center' : 
                   textArea.textAlign === 'right' ? 'flex-end' : 'flex-start',
    wordBreak: 'break-word',
    outline: 'none',
    padding: '4px'
  }
}

const selectTextLayer = (index: number) => {
  selectedTextIndex.value = index
}

const handleTextEdit = (index: number, event: Event) => {
  const target = event.target as HTMLElement
  const content = target.textContent || ''
  emit('text-edit', index, content)
}

const handleTextBlur = (index: number) => {
  // 文字编辑完成后的处理
}

const startMove = (index: number) => {
  isDragging.value = true
  selectedTextIndex.value = index
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

const startResize = (index: number, type: string) => {
  isResizing.value = true
  resizeType.value = type
  selectedTextIndex.value = index
  
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)
}

const handleMouseMove = (event: MouseEvent) => {
  if (!isDragging.value && !isResizing.value) return
  
  // 处理拖拽和缩放逻辑
  // 这里需要根据鼠标位置计算新的位置和大小
}

const handleMouseUp = () => {
  isDragging.value = false
  isResizing.value = false
  resizeType.value = ''
  
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

const handleGridToggle = () => {
  // 网格显示切换
}

const handleRulerToggle = () => {
  // 标尺显示切换
}

const resetCanvas = () => {
  selectedTextIndex.value = -1
  // 重置所有文字层位置
}

const centerContent = () => {
  // 居中所有内容
}

const exportImage = () => {
  exportDialogVisible.value = true
}

const confirmExport = async () => {
  if (!canvasRef.value) return
  
  exporting.value = true
  
  try {
    const canvas = await html2canvas(canvasRef.value, {
      backgroundColor: null,
      scale: exportConfig.sizeType === 'custom' ? 
        Math.min(exportConfig.width / props.template!.width, exportConfig.height / props.template!.height) : 1,
      width: exportConfig.sizeType === 'custom' ? exportConfig.width : props.template!.width,
      height: exportConfig.sizeType === 'custom' ? exportConfig.height : props.template!.height
    })
    
    const dataURL = canvas.toDataURL(`image/${exportConfig.format}`, exportConfig.quality)
    
    // 下载图片
    const link = document.createElement('a')
    link.download = `图文组合_${Date.now()}.${exportConfig.format}`
    link.href = dataURL
    link.click()
    
    emit('export-complete', dataURL)
    exportDialogVisible.value = false
    
    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  } finally {
    exporting.value = false
  }
}
</script>

<style scoped>
.live-preview {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  padding: 20px;
  color: white;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.preview-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}

.preview-actions {
  display: flex;
  gap: 15px;
  align-items: center;
}

.preview-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.preview-wrapper {
  transition: transform 0.3s ease;
}

.preview-canvas {
  background: white;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}

.background-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.image-layer {
  z-index: 2;
}

.canvas-image {
  display: block;
}

.text-layer {
  z-index: 3;
  user-select: none;
}

.text-layer.selected {
  z-index: 4;
}

.text-content {
  cursor: text;
}

.text-controls {
  position: absolute;
  top: -5px;
  left: -5px;
  right: -5px;
  bottom: -5px;
  pointer-events: none;
}

.control-point {
  position: absolute;
  width: 8px;
  height: 8px;
  background: #409EFF;
  border: 1px solid white;
  border-radius: 50%;
  pointer-events: all;
  cursor: pointer;
}

.control-point.top-left {
  top: 0;
  left: 0;
  cursor: nw-resize;
}

.control-point.top-right {
  top: 0;
  right: 0;
  cursor: ne-resize;
}

.control-point.bottom-left {
  bottom: 0;
  left: 0;
  cursor: sw-resize;
}

.control-point.bottom-right {
  bottom: 0;
  right: 0;
  cursor: se-resize;
}

.control-point.move {
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 20px;
  border-radius: 4px;
  background: #409EFF;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: move;
  color: white;
  font-size: 12px;
}

.grid-lines {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 10;
}

.grid-line {
  position: absolute;
  background: rgba(64, 158, 255, 0.3);
}

.grid-line.vertical {
  width: 1px;
  height: 100%;
}

.grid-line.horizontal {
  width: 100%;
  height: 1px;
}

.preview-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 10px;
  width: 100%;
}

.toolbar-section {
  display: flex;
  align-items: center;
  gap: 15px;
}

.canvas-info {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
}

/* 导出对话框样式 */
.size-inputs {
  display: flex;
  align-items: center;
  gap: 10px;
}

.size-inputs span {
  color: #666;
  font-weight: bold;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .live-preview {
    padding: 15px;
  }
  
  .preview-header {
    flex-direction: column;
    gap: 15px;
  }
  
  .preview-actions {
    width: 100%;
    justify-content: space-between;
  }
  
  .preview-toolbar {
    flex-direction: column;
    gap: 15px;
  }
  
  .toolbar-section {
    width: 100%;
    justify-content: space-between;
  }
}
</style>